/* QtLua -- Lua bindings for Qt
   Copyright (C) 2011, Jarek Pelczar

   This library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Lesser General Public
   License as published by the Free Software Foundation; either
   version 3 of the License, or (at your option) any later version.

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Lesser General Public License for more details.

   You should have received a copy of the GNU Lesser General
   Public License along with this library; if not, write to the
   Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301 USA

*/

#include "wrap_QSize.h"
#include "qluascriptvalue.h"
#include "qluascriptcontext.h"
#include "qluaexception.h"
#include <QDebug>

QSize_Prototype::QSize_Prototype(QObject * parent)
    : QObject(parent)
{
}

QSize * QSize_Prototype::ptr() const
{
    QSize * ptr = qtlua_scriptvalue_cast<QSize>(thisObject());
    if(!ptr) {
        engine()->throwException(engine()->newException(QLatin1String("QSize_prototype: Unable to cast this object to QSize")));
    }
    return ptr;
}

bool QSize_Prototype::isNull() const
{
    return ptr()->isNull();
}

bool QSize_Prototype::isEmpty() const
{
    return ptr()->isEmpty();
}

bool QSize_Prototype::isValid() const
{
    return ptr()->isValid();
}

int QSize_Prototype::getWidth() const
{
    return ptr()->width();
}

int QSize_Prototype::getHeight() const
{
    return ptr()->height();
}

void QSize_Prototype::setWidth(int x)
{
    ptr()->setWidth(x);
}

void QSize_Prototype::setHeight(int y)
{
    ptr()->setHeight(y);
}

QSizeF QSize_Prototype::toSizeF() const
{
    return QSizeF(*ptr());
}

void QSize_Prototype::transpose()
{
    ptr()->transpose();
}

void QSize_Prototype::scale(int w, int h, int mode)
{
    ptr()->scale(w, h, (Qt::AspectRatioMode)mode);
}

void QSize_Prototype::scale(const QSize &s, int mode)
{
    ptr()->scale(s, (Qt::AspectRatioMode)mode);
}

QSize QSize_Prototype::expandedTo(const QSize & s) const
{
    return ptr()->expandedTo(s);
}

QSize QSize_Prototype::boundedTo(const QSize & s) const
{
    return ptr()->boundedTo(s);
}

QSizeF * QSizeF_Prototype::ptr() const
{
    QSizeF * ptr = qtlua_scriptvalue_cast<QSizeF>(thisObject());
    if(!ptr) {
        engine()->throwException(engine()->newException(QLatin1String("QSizeF_prototype: Unable to cast this object to QSizeF")));
    }
    return ptr;
}

QSizeF_Prototype::QSizeF_Prototype(QObject * parent)
    : QObject(parent)
{
}

bool QSizeF_Prototype::isNull() const
{
    return ptr()->isNull();
}

bool QSizeF_Prototype::isEmpty() const
{
    return ptr()->isEmpty();
}

bool QSizeF_Prototype::isValid() const
{
    return ptr()->isValid();
}

qreal QSizeF_Prototype::getWidth() const
{
    return ptr()->width();
}

qreal QSizeF_Prototype::getHeight() const
{
    return ptr()->height();
}

void QSizeF_Prototype::setWidth(qreal x)
{
    ptr()->setWidth(x);
}

void QSizeF_Prototype::setHeight(qreal y)
{
    ptr()->setHeight(y);
}

QSize QSizeF_Prototype::toSize() const
{
    return ptr()->toSize();
}

void QSizeF_Prototype::transpose()
{
    ptr()->transpose();
}

void QSizeF_Prototype::scale(qreal w, qreal h, int mode)
{
    ptr()->scale(w, h, (Qt::AspectRatioMode)mode);
}

void QSizeF_Prototype::scale(const QSizeF &s, int mode)
{
    ptr()->scale(s, (Qt::AspectRatioMode)mode);
}

QSizeF QSizeF_Prototype::expandedTo(const QSizeF & s) const
{
    return ptr()->expandedTo(s);
}

QSizeF QSizeF_Prototype::boundedTo(const QSizeF & s) const
{
    return ptr()->boundedTo(s);
}

QSize_wrapper::QSize_wrapper(QLuaScriptEngine * engine)
    : QObject(engine),
      QLuaScriptClass(engine)
{
    m_proto = engine->newQObject(new QSize_Prototype(engine),
                                 QLuaScriptEngine::ScriptOwnership);

    engine->setGlobal("QSize", engine->newQObject(this));
    engine->setGlobal("QSize_prototype", m_proto);

    qluaRegisterScriptMetaType<QSize>(engine,
                                       QSize_toScriptValue,
                                       QSize_fromScriptValue);
}

QSize_wrapper::QueryFlags QSize_wrapper::queryProperty(const QLuaScriptValue& object,
                                 const QByteArray& name)
{
    if(name == "newSize") {
        return HandlesCallAccess;
    }

    return 0;
}

QLuaScriptValue QSize_wrapper::property(const QLuaScriptValue& object,
                                      const QByteArray& name)
{
    if(name == "newSize") {
        return scriptEngine()->newFunction(new_size);
    }

    return QLuaScriptValue();
}

QLuaScriptValue QSize_wrapper::prototype() const
{
    return m_proto;
}

QString QSize_wrapper::name() const
{
    return QLatin1String("QSize");
}

QLuaScriptValue QSize_wrapper::QSize_toScriptValue(QLuaScriptEngine * engine, const QSize * t)
{
    QLuaScriptValue value = engine->newUserDataWithGc<QSize>(engine->getGlobal("QSize_prototype"));
    QSize * obj = qtlua_scriptvalue_cast<QSize>(value);
    if(t)
        *obj = *t;
    return value;
}

void QSize_wrapper::QSize_fromScriptValue(const QLuaScriptValue& value, QSize * t)
{
    QSize * scriptT = qtlua_scriptvalue_cast<QSize>(value);
    if(scriptT) {
        *t = *scriptT;
    } else {
        qWarning("[QtLua] Trying to convert from another metatype of userdata to QSize");
    }
}

QLuaScriptValue QSize_wrapper::new_size(QLuaScriptContext * context, QLuaScriptEngine * engine)
{
    QLuaScriptValue value = engine->newUserDataWithGc<QSize>(engine->getGlobal("QSize_prototype"));
    QSize * obj = qtlua_scriptvalue_cast<QSize>(value);
    if(context->argumentCount() == 1)
    {
        if(QSize * p2 = qtlua_scriptvalue_cast<QSize>(context->argument(0))) {
            *obj = *p2;
        } else if(context->argument(0).isTable()) {
            obj->setWidth(context->argument(0).property("width").toInteger());
            obj->setHeight(context->argument(0).property("height").toInteger());
        }
    } else if(context->argumentCount() == 2) {
        obj->setWidth(context->argument(0).toInteger());
        obj->setHeight(context->argument(1).toInteger());
    }
    return value;
}

QSizeF_wrapper::QSizeF_wrapper(QLuaScriptEngine * engine)
    : QObject(engine),
      QLuaScriptClass(engine)
{
    m_proto = engine->newQObject(new QSizeF_Prototype(engine),
                                 QLuaScriptEngine::ScriptOwnership);

    engine->setGlobal("QSizeF", engine->newQObject(this));
    engine->setGlobal("QSizeF_prototype", m_proto);

    qluaRegisterScriptMetaType<QSizeF>(engine,
                                       QSizeF_toScriptValue,
                                       QSizeF_fromScriptValue);
}

QSizeF_wrapper::QueryFlags QSizeF_wrapper::queryProperty(const QLuaScriptValue& object,
                                 const QByteArray& name)
{
    if(name == "newSize") {
        return HandlesCallAccess;
    }

    return 0;
}

QLuaScriptValue QSizeF_wrapper::property(const QLuaScriptValue& object,
                                      const QByteArray& name)
{
    if(name == "newSize") {
        return scriptEngine()->newFunction(new_sizeF);
    }

    return QLuaScriptValue();
}

QLuaScriptValue QSizeF_wrapper::prototype() const
{
    return m_proto;
}

QString QSizeF_wrapper::name() const
{
    return QLatin1String("QSizeF");
}

QLuaScriptValue QSizeF_wrapper::QSizeF_toScriptValue(QLuaScriptEngine * engine, const QSizeF * t)
{
    QLuaScriptValue value = engine->newUserDataWithGc<QSizeF>(engine->getGlobal("QSizeF_prototype"));
    QSizeF * obj = qtlua_scriptvalue_cast<QSizeF>(value);
    if(t)
        *obj = *t;
    return value;
}

void QSizeF_wrapper::QSizeF_fromScriptValue(const QLuaScriptValue& value, QSizeF * t)
{
    QSizeF * scriptT = qtlua_scriptvalue_cast<QSizeF>(value);
    if(scriptT) {
        *t = *scriptT;
    } else {
        qWarning("[QtLua] Trying to convert from another metatype of userdata to QSizeF");
    }
}

QLuaScriptValue QSizeF_wrapper::new_sizeF(QLuaScriptContext * context, QLuaScriptEngine * engine)
{
    QLuaScriptValue value = engine->newUserDataWithGc<QSizeF>(engine->getGlobal("QSizeF_prototype"));
    QSizeF * obj = qtlua_scriptvalue_cast<QSizeF>(value);
    if(context->argumentCount() == 1)
    {
        if(QSizeF * p2 = qtlua_scriptvalue_cast<QSizeF>(context->argument(0))) {
            *obj = *p2;
        } if(QSize * p2 = qtlua_scriptvalue_cast<QSize>(context->argument(0))) {
            *obj = *p2;
        } else if(context->argument(0).isTable()) {
            obj->setWidth(context->argument(0).property("width").toNumber());
            obj->setHeight(context->argument(0).property("height").toNumber());
        }
    } else if(context->argumentCount() == 2) {
        obj->setWidth(context->argument(0).toNumber());
        obj->setHeight(context->argument(1).toNumber());
    }
    return value;
}

